Navigation System

**Referenced Files in This Document** - [navigation.js](file://src/assets/js/modules/navigation.js) - [main.js](file://src/assets/js/main.js) - [04-navigation.css](file://src/assets/css/modules/04-navigation.css) - [25-responsive-tablet-max-width-1024px.css](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css) - [26-responsive-mobile-max-width-900px.css](file://src/assets/css/modules/26-responsive-mobile-max-width-900px.css) - [43-mobile-menu-theme-aware-mobile-only.css](file://src/assets/css/modules/43-mobile-menu-theme-aware-mobile-only.css) - [scroll-nav-polish.js](file://src/assets/js/modules/scroll-nav-polish.js) - [theme-toggling.js](file://src/assets/js/modules/theme-toggling.js) - [material-design-3-main-theme-toggle.js](file://src/assets/js/modules/material-design-3-main-theme-toggle.js) - [iaa-alliance-theme-toggle.js](file://src/assets/js/modules/iaa-alliance-theme-toggle.js) - [base.njk](file://src/_includes/layouts/base.njk)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document explains the responsive navigation system with a mobile-first approach. It covers the hamburger menu behavior, breakpoint handling, active link highlighting, scroll position effects, theme-aware mobile menu styling, accessibility features (ARIA, keyboard, screen reader), navigation configuration, and practical customization examples. It also addresses performance considerations and extension guidance.

Project Structure

The navigation system spans JavaScript initialization, CSS breakpoints, and Nunjucks templates:

  • JavaScript initializes the mobile menu and scroll polish.
  • CSS defines desktop and mobile styles, animations, and theme-aware overrides.
  • Nunjucks provides the navigation markup and ARIA attributes.
graph TB
subgraph "Templates"
T1["base.njk"]
end
subgraph "JavaScript"
J1["navigation.js"]
J2["main.js"]
J3["scroll-nav-polish.js"]
J4["theme-toggling.js"]
J5["material-design-3-main-theme-toggle.js"]
J6["iaa-alliance-theme-toggle.js"]
end
subgraph "CSS"
C1["04-navigation.css"]
C2["25-responsive-tablet-max-width-1024px.css"]
C3["26-responsive-mobile-max-width-900px.css"]
C4["43-mobile-menu-theme-aware-mobile-only.css"]
end
T1 --> J2
J2 --> J1
J2 --> J3
J2 --> J4
J2 --> J5
J2 --> J6
J1 --> C1
J1 --> C2
J1 --> C3
J1 --> C4
J3 --> C1
J3 --> C2
J3 --> C3
J4 --> C1
J4 --> C2
J4 --> C3
J4 --> C4
J5 --> C1
J5 --> C2
J5 --> C3
J5 --> C4
J6 --> C1
J6 --> C2
J6 --> C3
J6 --> C4

Diagram sources

  • [base.njk:67-95](file://src/_includes/layouts/base.njk#L67-L95)
  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)
  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [scroll-nav-polish.js:1-19](file://src/assets/js/modules/scroll-nav-polish.js#L1-L19)
  • [theme-toggling.js:1-24](file://src/assets/js/modules/theme-toggling.js#L1-L24)
  • [material-design-3-main-theme-toggle.js:1-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L1-L38)
  • [iaa-alliance-theme-toggle.js:1-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L1-L38)
  • [04-navigation.css:1-101](file://src/assets/css/modules/04-navigation.css#L1-L101)
  • [25-responsive-tablet-max-width-1024px.css:1-174](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L1-L174)
  • [26-responsive-mobile-max-width-900px.css:1-79](file://src/assets/css/modules/26-responsive-mobile-max-width-900px.css#L1-L79)
  • [43-mobile-menu-theme-aware-mobile-only.css:1-84](file://src/assets/css/modules/43-mobile-menu-theme-aware-mobile-only.css#L1-L84)

Section sources

  • [base.njk:67-95](file://src/_includes/layouts/base.njk#L67-L95)
  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)

Core Components

  • Navigation initializer: toggles mobile menu, manages ARIA attributes, traps focus, closes on outside click and Escape, and focuses the first link after opening.
  • Scroll polish: adjusts nav padding/shadow on scroll.
  • Theme toggles: persist and reflect theme preferences and react to section-based theme changes.
  • CSS modules: define desktop/mobile layout, hamburger, full-screen mobile menu, staggered animations, and theme-aware overrides.

Key behaviors:

  • Active link highlighting via the active class on desktop.
  • Scroll position effects on desktop.
  • Automatic theme-aware mobile menu styling based on global theme classes.
  • Accessibility: ARIA-expanded, aria-label, aria-controls, Tab trapping, Escape to close.

Section sources

  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [scroll-nav-polish.js:1-19](file://src/assets/js/modules/scroll-nav-polish.js#L1-L19)
  • [theme-toggling.js:1-24](file://src/assets/js/modules/theme-toggling.js#L1-L24)
  • [material-design-3-main-theme-toggle.js:1-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L1-L38)
  • [iaa-alliance-theme-toggle.js:1-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L1-L38)
  • [04-navigation.css:1-101](file://src/assets/css/modules/04-navigation.css#L1-L101)
  • [25-responsive-tablet-max-width-1024px.css:1-174](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L1-L174)
  • [26-responsive-mobile-max-width-900px.css:1-79](file://src/assets/css/modules/26-responsive-mobile-max-width-900px.css#L1-L79)
  • [43-mobile-menu-theme-aware-mobile-only.css:1-84](file://src/assets/css/modules/43-mobile-menu-theme-aware-mobile-only.css#L1-L84)

Architecture Overview

The navigation system integrates markup, JS, and CSS with theme-awareness and responsive breakpoints.

sequenceDiagram
participant U as "User"
participant DOM as "DOM"
participant NavJS as "navigation.js"
participant ScrollJS as "scroll-nav-polish.js"
participant ThemeJS as "theme-toggling.js"
participant CSS as "CSS Modules"
U->>DOM : Click ".nav-toggle"
DOM->>NavJS : Event listener
NavJS->>DOM : Add ".active" to toggle/menu<br/>Add "menu-open" to body<br/>Set aria-expanded="true"
NavJS->>DOM : Focus first ".nav-link"
U->>DOM : Press Escape
DOM->>NavJS : keydown listener
NavJS->>DOM : Remove ".active"<br/>Remove "menu-open"<br/>Set aria-expanded="false"<br/>Focus toggle
U->>DOM : Click ".nav-link"
DOM->>NavJS : Event listener
NavJS->>DOM : Close menu if open
U->>DOM : Click outside menu
DOM->>NavJS : click listener
NavJS->>DOM : Close menu if open
U->>DOM : Scroll page
DOM->>ScrollJS : scroll listener
ScrollJS->>DOM : Adjust nav padding/shadow
DOM->>ThemeJS : Observe sections with "[data-theme]"
ThemeJS->>DOM : Toggle "on-light-bg"/"on-dark-bg"

Diagram sources

  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [scroll-nav-polish.js:1-19](file://src/assets/js/modules/scroll-nav-polish.js#L1-L19)
  • [theme-toggling.js:1-24](file://src/assets/js/modules/theme-toggling.js#L1-L24)
  • [04-navigation.css:1-101](file://src/assets/css/modules/04-navigation.css#L1-L101)
  • [25-responsive-tablet-max-width-1024px.css:1-174](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L1-L174)

Detailed Component Analysis

Mobile Menu Initialization and Behavior

Responsibilities:

  • Open/close state management.
  • ARIA attributes for accessibility.
  • Focus management and Tab trapping.
  • Outside click and Escape handling.
flowchart TD
Start(["initNavigation"]) --> Query["Query '.nav-toggle' and '.nav-menu'"]
Query --> Exists{"Both elements found?"}
Exists --> |No| Exit["Return (no-op)"]
Exists --> |Yes| Bind["Bind events"]
Bind --> ClickToggle["Click '.nav-toggle'"]
ClickToggle --> IsOpen{"'.nav-toggle' has '.active'?"}
IsOpen --> |Yes| Close["remove '.active'<br/>remove 'menu-open'<br/>aria-expanded=false<br/>focus toggle"]
IsOpen --> |No| Open["add '.active'<br/>add 'menu-open'<br/>aria-expanded=true<br/>focus first '.nav-link'"]
Bind --> ClickLink["Click '.nav-link'"]
ClickLink --> CloseOnLink{"Menu open?"}
CloseOnLink --> |Yes| Close
CloseOnLink --> |No| Noop1["No action"]
Bind --> KeydownDoc["keydown on document"]
KeydownDoc --> IsEsc{"key == 'Escape' and menu open?"}
IsEsc --> |Yes| Close
IsEsc --> |No| Noop2["No action"]
Bind --> KeydownMenu["keydown on '.nav-menu'"]
KeydownMenu --> Trap{"Trap Tab focus"}
Bind --> ClickOutside["click on document"]
ClickOutside --> OutsideCheck{"Menu open AND click outside?"}
OutsideCheck --> |Yes| Close
OutsideCheck --> |No| Noop3["No action"]
Open --> End(["Idle"])
Close --> End
Trap --> End
Noop1 --> End
Noop2 --> End
Noop3 --> End
Exit --> End

Diagram sources

  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)

Section sources

  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)

Desktop Navigation Styles and Active Links

Highlights:

  • Fixed-position nav with glass-like appearance.
  • Horizontal layout with logo and links.
  • Active link underline effect driven by the active class.
  • Hamburger toggle is hidden by default (desktop-only styles elsewhere).

Section sources

  • [04-navigation.css:1-101](file://src/assets/css/modules/04-navigation.css#L1-L101)

Responsive Breakpoints and Mobile Menu

Breakpoint handling:

  • Tablet breakpoint (max-width: 1024px) reveals the hamburger and applies full-screen mobile menu with a clip-path animation.
  • Mobile breakpoint (max-width: 900px) tightens spacing and font sizes.
  • On open, the menu expands from the hamburger position with staggered link animations.
flowchart TD
MW1024["max-width: 1024px"] --> ShowToggle["Display '.nav-toggle'"]
MW1024 --> Fullscreen["Apply full-screen '.nav-menu' styles"]
MW1024 --> ClipPath["clip-path: circle(0/150%)<br/>Transition from hamburger corner"]
MW1024 --> Stagger["Staggered '.nav-link' fade-in"]
MW900["max-width: 900px"] --> Tighten["Reduce padding/font sizes"]

Diagram sources

  • [25-responsive-tablet-max-width-1024px.css:1-174](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L1-L174)
  • [26-responsive-mobile-max-width-900px.css:1-79](file://src/assets/css/modules/26-responsive-mobile-max-width-900px.css#L1-L79)

Section sources

  • [25-responsive-tablet-max-width-1024px.css:1-174](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L1-L174)
  • [26-responsive-mobile-max-width-900px.css:1-79](file://src/assets/css/modules/26-responsive-mobile-max-width-900px.css#L1-L79)

Theme-Aware Mobile Menu

Behavior:

  • Mobile menu background and link colors adapt automatically to dark/light themes.
  • Additional overrides for IAA Alliance themed pages.
  • Hamburger icon and active state colors adjust per theme.
flowchart TD
ThemeDark["body: default dark"] --> NavMenuDark[".nav-menu: --navy"]
ThemeDark --> LinksDark[".nav-link: --white (hover: --gold, active: --gold)"]
ThemeLight["body.theme-light"] --> NavMenuLight[".nav-menu: --white + subtle shadow"]
ThemeLight --> LinksLight[".nav-link: --navy (hover: --sky-blue, active: --red)"]
ThemeLight --> HamburgerLight["'.nav-toggle span': --navy"]
IAA["body.iaa-page"] --> IAAOverrides["IAA-specific overrides"]

Diagram sources

  • [43-mobile-menu-theme-aware-mobile-only.css:1-84](file://src/assets/css/modules/43-mobile-menu-theme-aware-mobile-only.css#L1-L84)

Section sources

  • [43-mobile-menu-theme-aware-mobile-only.css:1-84](file://src/assets/css/modules/43-mobile-menu-theme-aware-mobile-only.css#L1-L84)

Accessibility Features

Implemented:

  • ARIA attributes on the toggle and menu.
  • Focus management: sets focus to the first link after opening.
  • Tab trapping inside the open menu.
  • Escape key to close the menu.
  • Outside click to close the menu.

Section sources

  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [base.njk:92-94](file://src/_includes/layouts/base.njk#L92-L94)

Navigation Configuration and Markup

The navigation is defined in the base layout with:

  • Logo with theme-appropriate variants.
  • Static links with active class applied server-side based on the current page.
  • Search toggle and navigation toggle with ARIA attributes.

To customize:

  • Add/remove links in the navigation list.
  • Apply the active class conditionally based on the current page.
  • Integrate external links by adding target and rel attributes as needed.

Section sources

  • [base.njk:67-95](file://src/_includes/layouts/base.njk#L67-L95)

Scroll Position Tracking and Visual Polish

Behavior:

  • On scroll, the nav reduces padding and adds a stronger shadow when scrolled past a threshold.
  • Uses a passive scroll listener for performance.

Section sources

  • [scroll-nav-polish.js:1-19](file://src/assets/js/modules/scroll-nav-polish.js#L1-L19)

Theme Detection and Persistence

Behavior:

  • Section intersection observer toggles body classes based on theme context.
  • Material Design 3 theme toggle persists user preference and reflects it in ARIA state.
  • IAA theme toggle operates independently with its own storage key.

Section sources

  • [theme-toggling.js:1-24](file://src/assets/js/modules/theme-toggling.js#L1-L24)
  • [material-design-3-main-theme-toggle.js:1-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L1-L38)
  • [iaa-alliance-theme-toggle.js:1-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L1-L38)

Dependency Analysis

High-level dependencies:

  • main.js orchestrates initialization of navigation and related modules.
  • navigation.js depends on CSS for mobile menu animations and theme-aware styles.
  • scroll-nav-polish.js depends on the nav element and window scroll.
  • theme toggles influence CSS via body classes.
graph LR
M["main.js"] --> N["navigation.js"]
M --> S["scroll-nav-polish.js"]
M --> TT["theme-toggling.js"]
M --> MT["material-design-3-main-theme-toggle.js"]
M --> IT["iaa-alliance-theme-toggle.js"]
N --> C1["04-navigation.css"]
N --> C2["25-responsive-tablet-max-width-1024px.css"]
N --> C3["26-responsive-mobile-max-width-900px.css"]
N --> C4["43-mobile-menu-theme-aware-mobile-only.css"]
S --> C1
S --> C2
S --> C3
TT --> C1
TT --> C2
TT --> C3
TT --> C4
MT --> C1
MT --> C2
MT --> C3
MT --> C4
IT --> C1
IT --> C2
IT --> C3
IT --> C4

Diagram sources

  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)
  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [scroll-nav-polish.js:1-19](file://src/assets/js/modules/scroll-nav-polish.js#L1-L19)
  • [theme-toggling.js:1-24](file://src/assets/js/modules/theme-toggling.js#L1-L24)
  • [material-design-3-main-theme-toggle.js:1-38](file://src/assets/js/modules/material-design-3-main-theme-toggle.js#L1-L38)
  • [iaa-alliance-theme-toggle.js:1-38](file://src/assets/js/modules/iaa-alliance-theme-toggle.js#L1-L38)
  • [04-navigation.css:1-101](file://src/assets/css/modules/04-navigation.css#L1-L101)
  • [25-responsive-tablet-max-width-1024px.css:1-174](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L1-L174)
  • [26-responsive-mobile-max-width-900px.css:1-79](file://src/assets/css/modules/26-responsive-mobile-max-width-900px.css#L1-L79)
  • [43-mobile-menu-theme-aware-mobile-only.css:1-84](file://src/assets/css/modules/43-mobile-menu-theme-aware-mobile-only.css#L1-L84)

Section sources

  • [main.js:1-37](file://src/assets/js/main.js#L1-L37)

Performance Considerations

  • Passive scroll listeners: scroll-nav-polish.js uses passive scrolling to avoid layout thrashing.
  • Event delegation: navigation.js attaches listeners directly to the toggle and menu; consider consolidating listeners if the number of items grows.
  • CSS transitions/animations: clip-path and opacity transforms are GPU-friendly; keep animations minimal.
  • Memory management: observers and event listeners are initialized once at startup; ensure no duplicate registrations occur.
  • Lazy loading: while not directly part of navigation, ensure heavy assets (images, videos) in content are lazy-loaded to keep navigation snappy.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and resolutions:

  • Menu does not open/close:
    • Verify the presence of ".nav-toggle" and ".nav-menu" elements.
    • Confirm initNavigation runs after DOMContentLoaded.
  • Focus trap not working:
    • Ensure ".nav-menu" contains focusable elements and the keydown handler is attached.
  • Escape key not closing menu:
    • Check the document-level keydown listener is attached and menu is open.
  • Outside click not closing menu:
    • Confirm the click listener checks containment and toggles state.
  • Active link highlight not appearing:
    • Ensure the active class is applied server-side in the template for the current page.
  • Mobile menu theme mismatch:
    • Confirm body classes reflect the intended theme and CSS selectors match.

Section sources

  • [navigation.js:1-78](file://src/assets/js/modules/navigation.js#L1-L78)
  • [base.njk:67-95](file://src/_includes/layouts/base.njk#L67-L95)

Conclusion

The navigation system is a cohesive, mobile-first implementation combining robust JavaScript behavior, responsive CSS, and theme-aware styling. It emphasizes accessibility, performance, and maintainability. The modular structure allows straightforward customization and extension.

[No sources needed since this section summarizes without analyzing specific files]

Appendices

Practical Examples

  • Customize menu items:

    • Edit the navigation list in the base layout to add or remove items.
    • Apply the active class conditionally based on the current page URL.
    • Example path: [base.njk:76-85](file://src/_includes/layouts/base.njk#L76-L85)
  • Integrate with CMS content:

    • Replace static links with dynamic entries generated from CMS data.
    • Ensure each link has appropriate ARIA attributes and external link handling (target and rel).
    • Example path: [base.njk:76-85](file://src/_includes/layouts/base.njk#L76-L85)
  • Extend navigation functionality:

    • Add dropdowns by nesting lists within ".nav-menu" and applying hover/focus behavior.
    • Implement keyboard navigation for dropdowns using arrow keys and Enter/Space.
    • Example path: [04-navigation.css:40-71](file://src/assets/css/modules/04-navigation.css#L40-L71)
  • Implement custom navigation patterns:

    • Duplicate the mobile menu animation pattern using clip-path and staggered transitions.
    • Example path: [25-responsive-tablet-max-width-1024px.css:104-144](file://src/assets/css/modules/25-responsive-tablet-max-width-1024px.css#L104-L144)
  • External link handling:

    • Add target="_blank" and rel="noopener noreferrer" to external links.
    • Example path: [base.njk:183-188](file://src/_includes/layouts/base.njk#L183-L188)

[No sources needed since this section aggregates guidance without quoting specific code]